package tech.hdis.framework.sms.aliyun;

import com.alibaba.fastjson.JSON;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.http.MethodType;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import tech.hdis.framework.sms.AuthCode;
import tech.hdis.framework.sms.AuthCodeMaker;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * 阿里云验证码实现
 *
 * @author 黄志文
 */
@Slf4j
@Component
public class AliyunAuthCodeImpl implements AuthCode {

    private static final String RESPONSE_CODE_OK = "OK";
    private static final Integer CACHE_SECONDS = 300;

    @Resource
    private IAcsClient client;
    @Resource
    private AliyunSmsProperties aliyunSmsProperties;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public boolean sendAuthCode(@NonNull String number) throws Exception {
        if (StringUtils.isEmpty(aliyunSmsProperties.getAuthTemplateCode())) {
            throw new NullPointerException("'hdis.aliyun.sms.authTemplateCode' property can not be null.please find it in your aliyun.");
        }
        //生成验证码
        String authCode = String.valueOf(AuthCodeMaker.randNum6());
        //组装验证码发送器
        SendSmsRequest request = new SendSmsRequest();
        request.setMethod(MethodType.POST);
        request.setPhoneNumbers(number);
        request.setSignName(aliyunSmsProperties.getSignName());
        request.setTemplateCode(aliyunSmsProperties.getAuthTemplateCode());
        request.setTemplateParam(JSON.toJSONString(Collections.singletonMap("code", authCode)));
        //发送验证码
        SendSmsResponse sendSmsResponse = client.getAcsResponse(request);
        if (sendSmsResponse != null) {
            log.debug("短信发送结果状态码：{}", sendSmsResponse.getCode());
            log.debug("短信发送结果信息：{}", sendSmsResponse.getMessage());
        }
        //发送成功后将验证码设置进缓存
        if (sendSmsResponse != null && sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals(RESPONSE_CODE_OK)) {
            BoundValueOperations<String, String> valueOps = stringRedisTemplate.boundValueOps(number);
            valueOps.set(authCode, CACHE_SECONDS, TimeUnit.SECONDS);
            return true;
        }
        return false;
    }

    @Override
    public boolean validationAuthCode(@NonNull String number, @NonNull String authCode) {
        BoundValueOperations<String, String> valueOps = stringRedisTemplate.boundValueOps(number);
        String existAuthCode = valueOps.get();
        return authCode.equals(existAuthCode);
    }
}
